package service

import (
	"context"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
	"lot_admin_api/api"
	"lot_admin_api/internal/consts"
	"lot_admin_api/internal/dao"
	"lot_admin_api/internal/model"
	GenInt64Id "lot_admin_api/utility/genInt64IdOfString"
	"lot_admin_api/utility/paging"
	"lot_admin_api/utility/response"
)

type sSite struct{}

var (
	insSite = sSite{}
)

func Site() *sSite {
	return &insSite
}

// AddSiteReq  新增站点
func (s *sSite) AddSiteReq(ctx context.Context, req *api.AddSiteReq) (id string, err error) {
	var saveInfo *model.SiteIdAndInfoRes // 定义数据类型
	r := g.RequestFromCtx(ctx)
	err = gconv.Scan(req, &saveInfo)              // 修改数据类型
	saveInfo.Id = GenInt64Id.GenInt64IdOfString() // 生成雪花id
	//userInfo := cache.StaffInfo(ctx)
	searchSiteLocation := &model.SiteLocation{
		SiteLatitude:  req.SiteLatitude,
		SiteLongitude: req.SiteLongitude,
	}
	err = s.NullLocationSite(ctx, searchSiteLocation)
	//saveInfo.CompanyId = userInfo.CompanyId
	if _, err := dao.LotSite.Ctx(ctx).Save(&saveInfo); err != nil {
		response.JsonExit(r, consts.HTTPInternalServer.Code(), "保存失败")
	} // 保存
	return saveInfo.Id, err
}

// NullLocationSite 判断不同的站点不能在同一经纬度上
func (s *sSite) NullLocationSite(ctx context.Context, req *model.SiteLocation) (err error) {
	r := g.RequestFromCtx(ctx)
	// 不能将不同站点放在同一经纬度上
	searchSite := g.Map{
		"site_longitude": req.SiteLongitude,
		"site_latitude":  req.SiteLatitude,
	}
	var findOne *model.SiteDbRes
	if err = dao.LotSite.Ctx(ctx).WithAll().Where(searchSite).Scan(&findOne); findOne != nil {
		response.JsonExit(r, consts.HTTPInternalServer.Code(), findOne.SiteName+"已占用该位置")
	}
	return err
}

// EditSite 编辑站点
func (s *sSite) EditSite(ctx context.Context, req *api.EditSiteReq) (id string, err error) {
	r := g.RequestFromCtx(ctx)
	findOne, err := s.SearchSiteInfo(ctx, req.Id)
	// 当经纬度完全相同时,判断是不是同意站点,不是不能修改传过来的经纬度 重点/不能将不同站点放在同一经纬度上
	if findOne.SiteLatitude == req.SiteLatitude && findOne.SiteLongitude == req.SiteLongitude {
		if findOne.Id != req.Id {
			// 不能将不同站点放在同一经纬度上
			searchSiteLocation := &model.SiteLocation{
				SiteLatitude:  req.SiteLatitude,
				SiteLongitude: req.SiteLongitude,
			}
			err = s.NullLocationSite(ctx, searchSiteLocation)
		}
	}
	//userInfo := cache.StaffInfo(ctx)
	//req.CompanyId = userInfo.CompanyId
	if _, err := dao.LotSite.Ctx(ctx).Where("id", req.Id).Update(&req); err != nil {
		response.JsonExit(r, consts.HTTPInternalServer.Code(), "编辑失败")
	} // 保存
	return req.Id, err
}

// DeleteSite 删除站点
func (s *sSite) DeleteSite(ctx context.Context, id string) (res *model.SiteIdRes, err error) {
	r := g.RequestFromCtx(ctx)
	_, err = s.SearchSiteInfo(ctx, id) // 查询是否有该站点
	if searchSiteList, err := dao.LotEquipment.Ctx(ctx).Where("site_id", id).All(); searchSiteList.Len() > 0 {
		response.JsonExit(r, consts.HTTPInternalServer.Code(), "请先解除该站点下的设备")
	} else if err != nil {
		response.JsonExit(r, consts.HTTPInternalServer.Code(), "查询站点下的方法错误")
	}
	if _, err = dao.LotSite.Ctx(ctx).Where("id", id).Delete(); err != nil {
		response.JsonExit(r, consts.HTTPInternalServer.Code(), "删除失败")
	}
	res = &model.SiteIdRes{
		Id: id,
	}
	return res, err
}

// SearchSiteInfo 查询站点
func (s *sSite) SearchSiteInfo(ctx context.Context, id string) (findOne *model.SiteDbRes, err error) {
	r := g.RequestFromCtx(ctx)
	if err = dao.LotSite.Ctx(ctx).WithAll().Where("id", id).Scan(&findOne); err != nil {
		response.JsonExit(r, consts.HTTPInternalServer.Code(), "查找站点失败")
	}
	if findOne == nil {
		response.JsonExit(r, consts.HTTPInternalServer.Code(), "没有该站点")
	}
	return findOne, err
}

// SiteList 获取站点列表
func (s *sSite) SiteList(ctx context.Context, req *model.SiteSearchList) (res *model.SiteListPageRes, err error) {
	siteList := make([]*model.SiteDbRes, 0)
	// 获取分页偏移量
	startNum, endNum := paging.Paging(req.Paging)
	condition := g.Map{
		"site_name like ?": "%" + req.SiteName + "%", // 模糊查询名字
		"id":               req.Id,                   // 查询Id
		"company_id":       req.CompanyId,            // 公司id
	}
	// 获取站点列表
	err = dao.LotSite.Ctx(ctx).OmitEmpty().WithAll().Where(condition).Limit(startNum, endNum).OrderDesc("created_at").Scan(&siteList)

	// 获取总条数
	countInfo, err := dao.LotSite.Ctx(ctx).OmitEmpty().Where(condition).Count()
	putCount := paging.PutCount(req.Paging, countInfo)
	res = &model.SiteListPageRes{
		List:    siteList,
		PutPage: *putCount,
	}
	return res, err
}
